/* Copyright by GD GameDuell GmbH, All Rights Reserved
 * This document is strictly confidential and sole property of GD GameDuell GmbH, Berlin, Germany
 */

package de.gameduell.framework.gui.animation {
	import fl.transitions.TweenEvent;

	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.EventDispatcher;

	/**
	 * @author Gevorg Sargsyan
	 */
	public class TimelineAnimation extends EventDispatcher implements Tweenable {

		protected var _clip:MovieClip;
		protected var _container:DisplayObjectContainer;
		protected var _loops:uint;
		protected var _loopCount:uint;
		protected var _autoStart:Boolean;
		protected var _autoDelete:Boolean;
		protected var _isCounting:Boolean;
		protected var _isNonStop:Boolean;
		protected var _isPlaying:Boolean;
		protected var _enableLabelEvents:Boolean;

		public function TimelineAnimation(clip:MovieClip, container:DisplayObjectContainer, playCount:uint, autoStart:Boolean, autoDelete:Boolean, enableLabelEvents : Boolean = false){
			_clip       = clip;
			_container  = container;
			_loopCount  = playCount;
			_loops      = 0;
			_autoStart  = autoStart; 
			_autoDelete = autoDelete;	
			_isCounting = false;
			_enableLabelEvents = enableLabelEvents;
			_clip 		= clip;
			_clip.stop();
			
			hide();
			_container.addChild(_clip);
			
			if(_loopCount != 0){
				_isNonStop = false; 
			}else{
				_isNonStop = true;
			}
			if(_autoStart ){
				start();
			}
			TweenManager.getInstance().add(this);
		}

		/**
		 * Gets the animation movieclip
		 * @return the movieclip of animation 
		 */
		public function get clip():MovieClip {
			return _clip;
		}

		/**
		 * Shows animation clip visually 
		 */
		public function show():void {
			_clip.visible = true;
		}

		/**
		 * Hides animation visually
		 */
		public function hide():void {
			_clip.visible = false;
		}

		/**
		 * Removes animation movieclip
		 */
		public function remove():void {
			detachFromEnterFrame();
			_container.removeChild(_clip);
			_clip = null;
			delete this;
		}

		/** 
		 * Starts animation
		 */
		public function start():void {
			_isPlaying = true;;
			show();
			if( !_isNonStop || _enableLabelEvents) {
				attachToEnterFrame();
			}
			_clip.play();
		}

		/**
		 * Pauses/stops animation
		 */
		public function stop():void {
			_isPlaying = false;
			if( !_isNonStop || _enableLabelEvents) {
				detachFromEnterFrame();
			}
			_clip.stop();
		}

		/**
		 * Resets animation, including number of counted loops
		 */
		public function reset():void {
			stop();
			_loops = 0;
			_clip.gotoAndStop(0);
		}

		protected function attachToEnterFrame():void {
			if(!_isCounting){
				_clip.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
				_isCounting = true;
			}
		}

		protected function detachFromEnterFrame():void {
			if(_isCounting) {
				_clip.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
				_isCounting = false;
			}
		}

		private function enterFrameHandler(event:Event):void {
			if(_enableLabelEvents == true && _clip.currentFrameLabel != null) {
				var timelineEvent:TimelineEvent = new TimelineEvent(TimelineEvent.LABEL_REACHED, _clip.currentFrame, _clip.currentFrameLabel);
				dispatchEvent(timelineEvent);
			}

			if(!_isNonStop) {
				if(_clip.currentFrame == _clip.framesLoaded) {
					_loops++;
					if(_loops == _loopCount) {
						stop();
						dispatchEvent(new TweenEvent(TweenEvent.MOTION_FINISH, 0, 0));
						if(_autoDelete == true) {
							remove();
						}
					}
				}
			}
		}

		public function get isPlaying():Boolean {
			return _isPlaying;
		}
	}	
}

